﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WJP
{
    /// <summary>
    /// 管理所有分支版本的路径及优先级
    /// </summary>
    public class BranchPathProvider
    {
        /// <summary>
        /// 各分支版本存放的文件夹名称。
        /// </summary>
        public const string BranchFilesRootDir = "BranchFiles";

        /// <summary>
        /// 主干版本的文件夹名。
        /// </summary>
        public const string CommonAppName = "Common";

        /// <summary>
        /// 所有的应用列表。
        /// 第一个是Common
        /// </summary>
        private List<string> _appNames;

        /// <summary>
        /// 所有客户文件夹所在的父文件夹路径
        /// </summary>
        private string _rootPath;

        internal BranchPathProvider()
        {
            _appNames = new List<string>();
            _appNames.Add("Common");
            _rootPath = PlatformEnvironment.MapAbsolutePath("BranchFiles");
        }

        /// <summary>
        /// 返回当前是否已经有分支版本进行了客户化。
        /// </summary>
        public bool HasBranch
        {
            get
            {
                return _appNames.Count > 1;
            }
        }

        /// <summary>
        /// 按照优先级调用此方法添加分支版本的路径。
        /// </summary>
        /// <param name="branchAppName"></param>
        internal void AddBranch(string branchAppName)
        {
            if (string.IsNullOrWhiteSpace(branchAppName))
                throw new ArgumentNullException(nameof(branchAppName));
            if (branchAppName == "Common")
                throw new ArgumentException("branchAppName 不能是Common");
            if (_appNames.Contains(branchAppName))
                return;
            _appNames.Insert(_appNames.Count - 1, branchAppName);
        }

        /// <summary>
        /// 根据提供的版本文件（夹）路径，按优先级返回所有版本对应的文件名。
        /// </summary>
        /// <param name="versionPath"></param>
        /// <param name="toAbsolute">是否转换为相对路径</param>
        /// <returns></returns>
        public string[] MapAllPathes(string versionPath, bool toAbsolute)
        {
            if (versionPath == null)
                throw new ArgumentNullException("relativePath");
            versionPath = versionPath.Replace('/', '\\');
            IEnumerable<string> source = _appNames.Select(n => Path.Combine(_rootPath, n, versionPath));
            if (!toAbsolute)
                source = source.Select(p => PlatformEnvironment.MapRelativePath(p));
            return source.ToArray();
        }

        /// <summary>
        /// 找到客户化相对路径所对应的文件，按照版本的优先级寻找。
        /// <para></para>从一个相对于版本目录的地址，获取到确切的文件相对地址，如：
        /// <para></para>Images/1.jpg
        /// =&gt;
        /// Files/DongFang/Images/1.jpg
        /// <para></para>其中，分支版本名是不确定的。
        /// </summary>
        /// <param name="versionPath">与分支版本无关的文件路径。</param>
        /// <returns></returns>
        public string GetCustomerFile(string versionPath)
        {
            string customerFile = FindCustomerFile(versionPath);
            if (customerFile == null)
                throw new ArgumentException("不存在这个文件或文件夹：" + versionPath);
            return customerFile;
        }

        /// <summary>
        /// 找到客户化相对路径所对应的文件，按照版本的优先级寻找。
        /// <para></para>从一个相对于版本目录的地址，获取到确切的文件相对地址，如：
        /// <para></para>Images/1.jpg
        /// =&gt;
        /// Files/DongFang/Images/1.jpg
        /// <para></para>其中，分支版本名是不确定的。
        /// </summary>
        /// <param name="versionPath">与分支版本无关的文件路径。</param>
        /// <returns></returns>
        public string FindCustomerFile(string versionPath)
        {
            if (string.IsNullOrEmpty(versionPath))
                throw new ArgumentNullException("relativePath");
            versionPath = versionPath.Replace('/', '\\');
            string path = null;
            if(path.IsNullOrEmpty())
                path = _appNames.FirstOrDefault(p => Directory.Exists(Path.Combine(_rootPath, p, versionPath)));
            return path;
        }
    }
}
